﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Web.Compilation;
using System.Web.Http;
using AOP;
using AOP.Interceptor;
using Autofac;
using Autofac.Core;
using Autofac.Integration.WebApi;
using Castle.DynamicProxy;

namespace AutofacDemo2.Common
{
    public static class IocHelper
    {
        static readonly ProxyGenerator _proxyGenerator = new ProxyGeneratorOptimize();
        static readonly IInterceptor _interceptor = new ElapseInterceptor();

        private static void GenerateProxyWhenActivating(IActivatingEventArgs<Object> e)
        {
            var instance = e.Instance;
            var proxiedInterfaces = instance.GetType().GetInterfaces().Where(i => i.IsVisible).ToArray();

            if (!proxiedInterfaces.Any())
            {
                return;
            }
            var theInterface = proxiedInterfaces.First();
            var interfaces = proxiedInterfaces.Skip(1).ToArray();
            IInterceptor interceptors = _interceptor;

            e.ReplaceInstance(_proxyGenerator.CreateInterfaceProxyWithTarget(theInterface, interfaces, instance, interceptors));
        }

        /// <summary>
        /// 构建容器
        /// </summary>
        public static void Build(string controller)
        {
            var builder = new ContainerBuilder();
            // Register the Web API controllers.
            builder.RegisterApiControllers(Assembly.Load(controller));

            var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>();
            // Register other dependencies.
            builder.RegisterServices(assemblies);

            IContainer container = builder.Build();
            AutofacWebApiDependencyResolver resolver = new AutofacWebApiDependencyResolver(container);
            GlobalConfiguration.Configuration.DependencyResolver = resolver;
        }

        //查找程序集中以Auto开头Services, DataAccess结尾的类型
        private static readonly Regex _servicesRegex = new Regex(@"Prefix.Service|Prefix.Dao|AutofacDemo");
        private static void RegisterServices(this ContainerBuilder builder, IEnumerable<Assembly> assemblies)
        {
            Assembly[] services = assemblies.Where(e => _servicesRegex.IsMatch(e.FullName)).ToArray();
            builder.RegisterAssemblyTypes(services)
                   .AsImplementedInterfaces()
                   .SingleInstance()
                   .OnActivating(GenerateProxyWhenActivating);
        }

    }
}